package com.zj.controller;

import com.zj.bean.CommonConfig;
import com.zj.bean.KeyValue;
import com.zj.bean.RunParams;
import com.zj.data.DataCenter;
import com.zj.job.CommonJob;
import com.zj.processors.CommonProcessor;
import com.zj.util.JsonUtil;
import de.felixroske.jfxsupport.FXMLController;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.*;

@FXMLController
public class CommonCtl implements Initializable {

    public Button startBtn;
    public TextArea logArea;

    public static Map<String, File> PROJECT_MAP = new HashMap<>();
    public ComboBox navContext;
    public ComboBox typeSelect;
//    public TextArea paramArea;
    public VBox paramPanel;
    public static Map<String,TextField> paramFieldMap;

    private static Map<String,CommonProcessor> processorMap;

    @Autowired
    private ApplicationContext applicationContext;
    
    public void log(final String log){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logArea.appendText(log);
                logArea.appendText("\n");
            }
        });
    }
    public void cleanLog(){
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                logArea.setText("");
            }
        });
    }

    public void alert(String msg){
        Alert alert = new Alert(Alert.AlertType.WARNING);
        alert.setTitle("提示");
        alert.setHeaderText(msg);
        alert.showAndWait();
    }

    public void startRun(ActionEvent actionEvent) {
        if (typeSelect.getSelectionModel() == null) {
            alert("请选择类型!");
            return;
        }
        String type=typeSelect.getSelectionModel().getSelectedItem().toString();
        RunParams runParams=DataCenter.getData("runParams", RunParams.class);
        for(KeyValue keyValue:runParams.getParams()){
            TextField textField = paramFieldMap.get(keyValue.getKey());
            keyValue.setValue(textField.getText());
        }

        log("保存参数。。。");
        runParams.setType(type);
        cleanLog();
        DataCenter.saveData("runParams",runParams);
        File paramsFile= DataCenter.getData("paramsFile",File.class);
        try {
            FileUtils.writeStringToFile(paramsFile, JsonUtil.obj2PrettyString(runParams),"utf-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        log("保存配置成功");


        new CommonJob(this,processorMap.get(type)).start();

    }


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        processorMap =applicationContext.getBeansOfType(CommonProcessor.class);

        File confDir = new File("./common_config");

        if(!confDir.exists()){
            System.out.println("no config directory!");
            return;
        }

        File[] fileList = confDir.listFiles();
        if(fileList==null || fileList.length == 0){
            System.out.println("no config file!");
            return;
        }
        //默认打开最近打开的
        int lastUseIndex=0;
        long lastTime=0;
        for (File configFile : fileList) {
            if (configFile.isDirectory()) {
                continue;
            }
            try {
                String json = FileUtils.readFileToString(configFile, "utf-8");
                CommonConfig config = JsonUtil.toObject(json, CommonConfig.class);
                PROJECT_MAP.put(config.getProjectName(), configFile);
                navContext.getItems().add(config.getProjectName());
                if (config.getLastUseTime() != null && config.getLastUseTime() > lastTime) {
                    lastTime=config.getLastUseTime();
                    lastUseIndex=navContext.getItems().size()-1;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

        ChangeProject changeListener= new ChangeProject();
        navContext.setOnAction(changeListener);
        if (PROJECT_MAP.size() > 0) {
            navContext.getSelectionModel().select(lastUseIndex);
            changeListener.handle(null);
        }

        for(String templateProcessor:processorMap.keySet()){
            typeSelect.getItems().add(templateProcessor);
        }
    }

    private void showParams(List<KeyValue> keyValueList) {
        paramFieldMap = new HashMap<>();
        paramPanel.getChildren().removeAll(paramPanel.getChildren());
        for (KeyValue keyValue : keyValueList) {
            TextField textField = new TextField();
            textField.setText(keyValue.getValue());
            textField.setPrefWidth(keyValue.getTextWidth()==null ? 500 :keyValue.getTextWidth());

            paramFieldMap.put(keyValue.getKey(),textField);
            Label label = new Label(keyValue.getKey());
            label.setPrefWidth(keyValue.getLabelWidth()==null? 130:keyValue.getLabelWidth());

            Label description = new Label(keyValue.getDescription());
            description.setPrefWidth(keyValue.getDescriptionWidth()==null? 200:keyValue.getDescriptionWidth());


            HBox hBox = new HBox();
            hBox.getChildren().add(label);
            hBox.getChildren().add(textField);
            hBox.getChildren().add(description);
            Insets insets=new Insets(10.0,10.0,10.0,10.0);
            hBox.setPadding(insets);
            paramPanel.getChildren().add(hBox);
        }
    }

    public void setInputValue(File configFile){
        CommonConfig currentConfig = JsonUtil.prettyFileToObject(configFile, CommonConfig.class);
        if (currentConfig != null) {
            currentConfig.setLastUseTime(System.currentTimeMillis());
            try {
                FileUtils.writeStringToFile(configFile, JsonUtil.obj2PrettyString(currentConfig),"utf-8");
                log("当前项目 ------------ "+currentConfig.getProjectName());
            } catch (IOException e) {
                e.printStackTrace();
            }
            DataCenter.saveData("commonConfig",currentConfig);
            DataCenter.saveData("commonConfigFile",configFile);
            if (currentConfig.getParamFile() != null) {
                String paramFilePath = configFile.getParentFile().getAbsolutePath() + File.separator +"params"+File.separator+ currentConfig.getParamFile();
                File paramFile = new File(paramFilePath);
                if (paramFile.exists()) {
                    DataCenter.saveData("paramsFile",paramFile);
                    RunParams runParams=JsonUtil.prettyFileToObject(paramFile, RunParams.class);
                    if (runParams != null ) {
                        DataCenter.saveData("runParams",runParams);

                        if(runParams.getType() != null){
                            typeSelect.getSelectionModel().select(runParams.getType());
                        }
//                        paramArea.setText(JsonUtil.obj2PrettyString(runParams));
                        showParams(runParams.getParams());
                    }
                }
            }
        }
    }


    public void openProjectConfig(ActionEvent actionEvent) {
        Stage stage = new Stage();
        Parent projectConfigView = null;
        try {
            projectConfigView = FXMLLoader.load(getClass().getResource("/ProjectConfig.fxml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scene scene = new Scene(projectConfigView,888,488);
        stage.setScene(scene);
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.show();
    }

    class ChangeProject<ActionEvent> implements EventHandler {

        @Override
        public void handle(Event event) {
            String key= navContext.getSelectionModel().getSelectedItem().toString();
            setInputValue(PROJECT_MAP.get(key));
        }
    }

}
